package com.cskaoyan.aspect;

import com.cskaoyan.bean.BaseRespVo;
import com.cskaoyan.bean.pojo.Admin;
import com.cskaoyan.bean.pojo.Log;
import com.cskaoyan.mapper.AdminMapper;
import com.cskaoyan.mapper.LogMapper;
import lombok.SneakyThrows;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Classname LogAspect
 * @Description
 * @Date 2021/8/16 15:57
 * @Created by songweinan
 */
@Aspect
@Component
public class CustomLogAspect {

    @Autowired
    LogMapper logMapper;

    @Autowired
    AdminMapper adminMapper;

    private final String LOGIN = "/admin/auth/login";
    private final String LOGOUT = "/admin/auth/logout";
    private final String ADMIN_CREATE = "/admin/admin/create";
    private final String ADMIN_DELETE = "/admin/admin/delete";
    private final String ADMIN_UPDATE = "/admin/admin/update";

    @Pointcut("execution(* com..controller.admin..login(..))")
    public void login(){
    }

    @Pointcut("execution(* com..controller.admin..logout(..))")
    public void logout(){
    }

    @Pointcut("execution(* com..controller.admin.AdminController.create(..))")
    public void admincreate(){
    }

    @Pointcut("execution(* com..controller.admin.AdminController.delete(..))")
    public void admindelete(){
    }

    @Pointcut("execution(* com..controller.admin.AdminController.update(..))")
    public void adminupdate(){
    }

    @SneakyThrows
    @AfterReturning(value = "login()||admincreate()||admindelete()||adminupdate()",returning = "result")
    public void afterLog(BaseRespVo result){

        Log log = new Log();

        String admin = (String) SecurityUtils.getSubject().getPrincipal();
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
        String remoteAddr = request.getRemoteAddr();
        String requestURI = request.getRequestURI();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date addTime = sdf.parse(sdf.format(new Date()));

        String action = getOptionAction(requestURI,remoteAddr,addTime);

        log.setId(null);
        log.setAdmin(admin);
        log.setIp(remoteAddr);
        log.setType(1);
        log.setAction(action);
        if(result.getErrno() == 0){
            log.setStatus(true);
        }else{
            log.setStatus(false);
        }
        log.setResult("");
        log.setComment("");
        log.setAddTime(addTime);
        log.setUpdateTime(addTime);
        log.setDeleted(false);

        int insert = logMapper.insert(log);
    }

    @SneakyThrows
    @Before("logout()")
    public void beforeLog(){

        Log log = new Log();

        String admin = (String) SecurityUtils.getSubject().getPrincipal();
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes)requestAttributes).getRequest();
        String remoteAddr = request.getRemoteAddr();
        String requestURI = request.getRequestURI();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date addTime = sdf.parse(sdf.format(new Date()));

        String action = getOptionAction(requestURI,remoteAddr,addTime);

        log.setId(null);
        log.setAdmin(admin);
        log.setIp(remoteAddr);
        log.setType(1);
        log.setAction(action);
        log.setStatus(true);
        log.setResult("");
        log.setComment("");
        log.setAddTime(addTime);
        log.setUpdateTime(addTime);
        log.setDeleted(false);

        int insert = logMapper.insert(log);
    }

    private String getOptionAction(String uri,String remoteAddr,Date updateTime) {

        if(LOGIN.equals(uri)){
            //更改admin表中上次登录的ip和时间
            Boolean isUpdateSuccess = updateIpAndTime(remoteAddr, updateTime);

            return "登录";
        }else if(LOGOUT.equals(uri)){
            return "登出";
        }else if(ADMIN_CREATE.equals(uri)){
            return "创建管理员信息";
        }else if(ADMIN_DELETE.equals(uri)){
            return "删除管理员信息";
        }else if(ADMIN_UPDATE.equals(uri)){
            return "修改管理员信息";
        }
        return "";
    }

    private Boolean updateIpAndTime(String remoteAddr, Date updateTime) {

        String adminName = (String) SecurityUtils.getSubject().getPrincipal();
        Integer adminId = adminMapper.selectIdByName(adminName);
        Admin admin = new Admin();
        admin.setId(adminId);
        admin.setLastLoginIp(remoteAddr);
        admin.setLastLoginTime(updateTime);
        int i = adminMapper.updateByPrimaryKeySelective(admin);
        return true;
    }
}
